﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleAlgorithms.Tests
{
    public class C07_MatchSchedule : ITestable
    {
        public void Test()
        {
            int k = 4;
            var schedule = MakeSchedule(k);
            PrintSchedule(schedule);
        }

        /// <summary>
        /// 制作比赛赛程表格。
        /// </summary>
        /// <param name="schedule"></param>
        public List<List<int>> MakeSchedule(int k)
        {
            int n = (int)Math.Pow(2, k) + 1;
            List<List<int>> schedule = new List<List<int>>();
            for (int i = 0; i < n; i++)
            {
                var list = new List<int>();
                for (int j = 0; j < n; j++)
                    list.Add(j);
                schedule.Add(list);
            }

            //初始化表格第一行 
            for (int i = 1; i < n; i++)
                schedule[1][i] = i;


            int m = 1;
            for (int s = 1; s <= k; s++)
            {
                n /= 2;
                for (int t = 1; t <= n; t++)
                {
                    //对每一部分进行划分（达到分治目的） 
                    for (int i = 1 + m; i <= 2 * m; i++)
                    {
                        //控制行 
                        for (int j = 1 + m; j <= 2 * m; j++)
                        {
                            //控制列 
                            schedule[i][j + (t - 1) * m * 2] = schedule[i - m][j + (t - 1) * m * 2 - m];  //右下角等左于上角的值 
                            schedule[i][j + (t - 1) * m * 2 - m] = schedule[i - m][j + (t - 1) * m * 2];  //左下角等于右上角的值 
                        }
                    }
                }
                m *= 2;
            }

            return schedule;
        }


        /// <summary>
        /// 打印日程表。
        /// </summary>
        /// <param name="schedule">日程表。</param>
        public void PrintSchedule(List<List<int>> schedule)
        {
            int n = schedule.Count - 1;
            Console.Write($"比赛日程表：\n{"d ",4}|");
            for (int i = 0; i < n - 1; i++)
                Console.Write($"{i + 1,5}");
            Console.WriteLine("\n" + new string('-', (n + 1) * 5));

            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= n; j++)
                {
                    Console.Write($"{schedule[i][j], 3}");
                    Console.Write( j != 1 ?   "  " :  " |  ");
                }
                Console.WriteLine();
            }
            Console.WriteLine(new string('-', (n + 1) * 5));
        }

    }
}
